<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    width="40%"
    top="10vh"
    :before-close="closeDialogHandle"
    :close-on-click-modal="false"
  >
    <el-form size="mini" :model="limitConfig" :rules="limitConfigRules" ref="limitConfigForm" @keyup.enter.native="submitHandle" label-width="115px">
      <el-form-item label="" prop="defaultFlag">
        <el-radio-group v-model="limitConfig.defaultFlag" :disabled="optType" @input="changeDefaultFlagHandle">
          <el-radio :label="1" border>接口配置</el-radio>
          <el-radio :label="0" border>默认配置</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="接口路径" prop="requestKey">
        <el-input v-model="limitConfig.requestKey" :disabled="limitConfig.defaultFlag === 0 || optType" clearable placeholder="请输入接口路径" class="width90percent"></el-input>
      </el-form-item>
      <el-form-item label="限流类型" prop="type">
        <el-radio-group v-model="limitConfig.type" :disabled="optType">
          <el-radio v-for="typeEnum in typeEnumList" :key="'type' + typeEnum.value"
                    :label="typeEnum.value" border>{{ typeEnum.name }}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="时间数值" prop="timeNum">
        <el-input v-model.number="limitConfig.timeNum" clearable placeholder="请输入时间数值" class="width90percent"></el-input>
      </el-form-item>
      <el-form-item label="时间单位" prop="timeType">
        <el-select v-model="limitConfig.timeType" placeholder="请选择时间单位" class="width90percent">
          <el-option
            v-for="timeTypeEnum in timeTypeEnumList"
            :key="'request' + timeTypeEnum.value"
            :label="timeTypeEnum.name"
            :value="timeTypeEnum.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="滑动窗口数量" prop="windowNum">
        <el-input v-model.number="limitConfig.windowNum" clearable placeholder="请输入滑动窗口数量" class="width90percent"></el-input>
      </el-form-item>
      <el-form-item label="最大次数" prop="maxNum">
        <el-input v-model.number="limitConfig.maxNum" clearable placeholder="请输入最大次数" class="width90percent"></el-input>
      </el-form-item>
      <el-form-item label="限流时长" prop="limitTime">
        <el-input v-model.number="limitConfig.limitTime" clearable placeholder="请输入限流时长" class="width90percent">
          <template slot="append">秒</template>
        </el-input>
      </el-form-item>
      <el-form-item label="限流回复消息" prop="message">
        <el-input v-model="limitConfig.message" clearable maxlength="20" show-word-limit placeholder="请输入限流回复消息" class="width90percent"></el-input>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="limitConfig.status">
          <el-radio v-for="statusEnum in statusEnumList" :key="'status' + statusEnum.value"
                    :label="statusEnum.value" border>{{ statusEnum.name }}</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="closeDialogHandle(false)">取 消</el-button>
      <el-button v-show="!optType" :disabled="buttonLoad" type="primary" @click="saveHandle">添 加</el-button>
      <el-button v-show="optType" :disabled="buttonLoad" type="primary"  @click="updateHandle">修 改</el-button>
    </span>
  </el-dialog>
</template>

<script>
  export default {
    name: "limit-config-dialog",
    props: {
      // 限流类型枚举列表
      typeEnumList: {
        type: Array,
        default: () => []
      },
      // 时间枚举列表
      timeTypeEnumList: {
        type: Array,
        default: () => []
      },
      // 状态枚举列表
      statusEnumList: {
        type: Array,
        default: () => []
      },
    },
    data() {
      let checkRequestKey = (rule, value, callback) => {
        if (this.limitConfig.defaultFlag === 0 || value !== '') {
          return callback()
        }
        callback(new Error('接口路径不能为空'))
      }
      let checkTimeNum = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('请输入时间数值'))
        }
        if (!/^[+]?(\d+)$/.test(value)) {
          return callback(new Error('请输入正确的时间数值'))
        }
        callback()
      }
      let checkWindowNum = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('请输入滑动窗口数量'))
        }
        if (!/^[+]?(\d+)$/.test(value)) {
          return callback(new Error('请输入正确的滑动窗口数量'))
        }
        callback()
      }
      let checkMaxNum = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('请输入最大次数'))
        }
        if (!/^[+]?(\d+)$/.test(value)) {
          return callback(new Error('请输入正确的最大次数'))
        }
        callback()
      }
      let checkLimitTime = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('请输入限流时长'))
        }
        if (!/^[+]?(\d+)$/.test(value)) {
          return callback(new Error('请输入正确的限流时长'))
        }
        callback()
      }

      return {
        // 弹出框显示状态[true-显示 false-关闭]
        visible: false,
        // 弹出框标题
        title: undefined,
        // 限流配置操作类型[false-添加 true-修改]
        optType: false,
        // 限流配置对象
        limitConfig: {
          // 是否默认限流配置[0-是 1-否]
          defaultFlag: 1,
          // 接口路径
          requestKey: '',
          // 限流类型[0-请求 1-异常]
          type: '',
          // 时间数值
          timeNum: '',
          // 时间单位[0-秒 1-分 2-时 3-日 4-月 5-年]
          timeType: 0,
          // 滑动窗口数量
          windowNum: '',
          // 最大次数
          maxNum: '',
          // 限流时长（秒）
          limitTime: '',
          // 限流回复消息
          message: '',
          // 版本号
          version: undefined,
          // 状态[0-可用 1-不可用]
          status: 0
        },
        // 限流配置表单校验规则对象
        limitConfigRules: {
          requestKey: [
            { required: true, validator: checkRequestKey, trigger: 'blur' }
          ],
          type: [
            { required: true, message: '请选择限流类型', trigger: 'change' }
          ],
          timeNum: [
            { required: true, validator: checkTimeNum, trigger: 'blur' }
          ],
          windowNum: [
            { required: true, validator: checkWindowNum, trigger: 'blur' }
          ],
          maxNum: [
            { required: true, validator: checkMaxNum, trigger: 'blur' }
          ],
          limitTime: [
            { required: true, validator: checkLimitTime, trigger: 'blur' }
          ],
          message: [
            { required: true, message: '请输入限流回复消息', trigger: 'blur' }
          ]
        },
        // 按钮禁用状态[true-禁用 false-可用]
        buttonLoad: false,

      }
    },
    methods: {
      /**
       * 初始化弹出框方法
       * @param {Object} limitConfig 限流配置对象
       */
      initDialog(limitConfig) {
        // 打开弹出框
        this.visible = true;

        let _limitConfig = this.limitConfig;
        if (limitConfig) {
          this.title = "修改限流配置";
          this.optType = true;

          this.$nextTick(() => {
            for (let propKey in _limitConfig) {
              if (limitConfig.hasOwnProperty(propKey)) {
                _limitConfig[propKey] = limitConfig[propKey];
              }
            }
            _limitConfig.defaultFlag = _limitConfig.requestKey === 'default' ? 0 : 1;
          });
        } else {
          this.title = "新增限流配置";
          this.optType = false;
        }
      },
      /**
       * 初始化保存限流配置方法
       * @param {string} requestKey 接口路径
       */
      saveInit(requestKey) {
        // console.log("requestKey", requestKey);
        // 打开弹出框
        this.visible = true;
        this.title = "新增限流配置";
        this.optType = false;

        this.limitConfig.requestKey = requestKey;
        this.limitConfig.defaultFlag = 1;
      },
      /**
       * 默认配置切换事件
       * @param {number} value 最新值
       */
      changeDefaultFlagHandle(value) {
        this.limitConfig.requestKey = '';
        if (value === 0) {
          this.limitConfig.requestKey = 'default';
          // 清理 接口路径 的校验状态
          this.$refs.limitConfigForm.clearValidate('requestKey')
        }
      },
      /**
       * 提交限流配置操作
       */
      submitHandle() {
        if (this.optType) {
          this.updateHandle();
        } else {
          this.saveHandle();
        }
      },
      /**
       * 保存限流配置事件
       */
      saveHandle() {
        this.$refs.limitConfigForm.validate((valid) => {
          if (!valid) {
            return false;
          }
          // console.log('limitConfig', this.limitConfig);
          // 按钮禁止使用
          this.buttonLoad = true;
          let checkFlag;
          this.$axios.$post('/sys/limit-config/check', this.limitConfig)
            .then(({ data }) => {
              checkFlag = data.checkFlag;
              this.limitConfig.version = data.version;

              let promise = Promise.resolve();
              if (data.checkFlag) {
                // 校验拒绝
                promise = this.$confirm('已存在可用的限流配置数据，是否要新增限流配置，停用旧的限流配置?', '保存提示', {
                  confirmButtonText: '确定',
                  cancelButtonText: '取消',
                  type: 'warning'
                });
              }
              return promise;
            })
            .then(() => {
              return this.$axios.$post('/sys/limit-config/save', this.limitConfig, { params: { checkFlag: checkFlag}});
            })
            .then(() => {
              this.notify('success', '操作成功', '新限流配置添加成功');

              this.closeDialogHandle(true);
            })
            .catch(() => {})
            .finally(() => {
              // 按钮恢复可用
              this.buttonLoad = false;
            })
        });
      },
      /**
       * 更新限流配置事件
       */
      updateHandle() {
        this.$refs.limitConfigForm.validate((valid) => {
          if (!valid) {
            return false;
          }
          // 按钮禁止使用
          this.buttonLoad = true;
          this.$axios.$post('/sys/limit-config/update', this.limitConfig)
            .then(() => {
              this.notify('success', '操作成功', '限流配置修改成功')

              this.closeDialogHandle(true);
            })
            .catch(() => {})
            .finally(() => {
              this.buttonLoad = false;
            })
        });
      },
      /**
       * 关闭弹出框方法
       * @param {boolean | function} refresh 是否刷洗父级组件数据
       */
      closeDialogHandle(refresh) {
        // 重置表单
        this.$refs.limitConfigForm.resetFields();
        this.limitConfig.version = undefined;

        // console.log('limitConfig', this.limitConfig);
        if (typeof refresh === 'function') {
          refresh = false;
        }
        // 向上传递事件
        this.$emit('close-dialog', refresh);
        this.$nextTick(() => {
          // 关闭弹出框
          this.visible = false;
        });
      }
    }
  }
</script>

<style scoped>
  .width90percent {
    width: 90%;
  }
</style>
